//
//  GLGridView.m
//  KTools
//
//  Created by zhiyong.kuang on 2017/9/22.
//  Copyright © 2017年 zhiyong.kuang. All rights reserved.
//
//
//                            _ooOoo_
//                           o8888888o
//                           88" . "88
//                           (| -_- |)
//                            O\ = /O
//                        ____/`---'\____
//                      .   ' \\| |// `.
//                       / \\||| : |||// \
//                     / _||||| -:- |||||- \
//                       | | \\\ - /// | |
//                     | \_| ''\---/'' | |
//                      \ .-\__ `-` ___/-. /
//                   ___`. .' /--.--\ `. . __
//                ."" '< `.___\_<|>_/___.' >'"".
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |
//                 \ \ `-. \_ __\ /__ _/ .-` / /
//         ======`-.____`-.___\_____/___.-`____.-'======
//                            `=---='
//
//         .............................................
//                  佛祖镇楼                  BUG辟易

#import "GLGridView.h"

#import "Masonry.h"

/*
 @description 默认值
 */
#define GLGRIDDEFAULT_LINEWIDTH 1.0/[UIScreen mainScreen].scale
#define GLGRIDDEFAULT_HEIGHT 60
#define GLGRIDDEFAULT_ROWCOUNT 4

#define GLGRIDDEFAULT_EDIT_DEL_TAG 95632
#define GLGRIDDEFAULT_EDIT_ADD_TAG 95633


static NSString * const kCellID = @"GLGridCollectionCell";
static NSString * const kNullCellID = @"GLNullGridCollectionCell";


#pragma mark- CLASS GLGridView

@interface GLGridView ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

@property(nonatomic, strong) UICollectionView *collectionView;
@property(nonatomic, strong) BindCellAndDataBlock bindDataBlock;
@property(nonatomic,assign) CGFloat itemWidth;
/*
 所有数据源数，当真实数据不满一行时，会添加补充CELL
 */
@property(nonatomic,assign) NSInteger allCount;
@property(nonatomic,assign) Class registerCellClass;
@property(nonatomic,strong) UIImageView* moveItem;
@property(nonatomic,strong) NSIndexPath* orignIndexPath;

@property(nonatomic,strong) NSIndexPath* curMoveIndexPath;
@property(nonatomic,strong) UILongPressGestureRecognizer *longPressGesture;
@end

@implementation GLGridView

#pragma mark- life cycle
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self configDefaultData];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self configDefaultData];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self configDefaultData];
    }
    return self;
}


#pragma mark UI DATA init
/*
 @description 配置默认值
 */
- (void)configDefaultData{
    self.lineWidth = GLGRIDDEFAULT_LINEWIDTH;
    self.itemWidth = GLGRIDDEFAULT_HEIGHT;
    self.rowCount = GLGRIDDEFAULT_ROWCOUNT;
    self.showLine = YES;
    self.itemMoveType = GLGridViewOperationTypeEditing;
    self.itemDeleteType = GLGridViewOperationTypeEditing;
    self.itemAddType = GLGridViewOperationTypeEditing;
    self.editable = NO;
    self.delBtnSize = CGSizeMake(40, 25);
    self.addBtnSize = CGSizeMake(60, 60);
    self.backgroundColor = [UIColor whiteColor];
}

- (BOOL)judgeOperationType:(GLGridViewOperationType)type{
    if (type == GLGridViewOperationTypeAways) {
        return YES;
    }
    if (type == GLGridViewOperationTypeEditing && self.editable) {
        return YES;
    }
    
    return NO;
}


- (void)setupUI
{
    
    [self addSubview:self.collectionView];
    [self.collectionView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.equalTo(self);
    }];
    
    if ([self judgeOperationType:self.itemMoveType]) {
        if (!_longPressGesture) {
            _longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
            [_collectionView addGestureRecognizer:_longPressGesture];
        }
    }else{
        if (_longPressGesture) {
            [_collectionView removeGestureRecognizer:_longPressGesture];
            _longPressGesture = nil;
        }
        
    }
    
}


#pragma mark- api
-(void)registerCell:(Class)cellClass bind:(BindCellAndDataBlock)dataBind{
    self.registerCellClass = cellClass;
    self.bindDataBlock = dataBind;
    
}
-(void)reloadData{
    [self setupUI];
    
    
    [self.collectionView reloadData];
    
}

#pragma mark - UICollectionViewDelegate, UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSInteger num = self.allCount;
    return num;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell* cell = nil;
    
    if(indexPath.row < self.dataArray.count){
        cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
        //将cell返回给调用者进行数据与CELL绑定
        if (self.bindDataBlock) {
            id value = [self.dataArray objectAtIndex:indexPath.row];
            self.bindDataBlock(cell,indexPath,value);
        }
        
        if ([self judgeOperationType:self.itemDeleteType]) {
            UIButton* delButton = [cell.contentView viewWithTag:GLGRIDDEFAULT_EDIT_DEL_TAG];
            if (!delButton) {
                delButton = [UIButton buttonWithType:UIButtonTypeCustom];
                delButton.tag = GLGRIDDEFAULT_EDIT_DEL_TAG;
                
                delButton.frame = CGRectMake(cell.bounds.size.width-self.delBtnSize.width, 0, self.delBtnSize.width, self.delBtnSize.height);
                [delButton addTarget:self action:@selector(deleteCell:) forControlEvents:UIControlEventTouchUpInside];
                if (self.delImage) {
                    [delButton setImage:self.delImage forState:UIControlStateNormal];
                }else{
                    [delButton setTitle:@"del" forState:UIControlStateNormal];
                    delButton.backgroundColor = [UIColor greenColor];
                }
                
                [cell.contentView addSubview:delButton];
            }
            
        }else{
            UIButton* delBtn = [cell.contentView viewWithTag:GLGRIDDEFAULT_EDIT_DEL_TAG];
            if (delBtn) {
                [delBtn removeFromSuperview];
            }
        }
        
    }else{
        
        //当CELL不满一行时，进行填充，补满一行
        cell = [collectionView dequeueReusableCellWithReuseIdentifier:kNullCellID forIndexPath:indexPath];
        cell.contentView.backgroundColor = [UIColor clearColor];
        cell.backgroundColor = [UIColor clearColor];
        
        if ([self judgeOperationType:self.itemAddType] && indexPath.row == self.dataArray.count) {
            UIButton* addButton = [cell.contentView viewWithTag:GLGRIDDEFAULT_EDIT_ADD_TAG];
            if (!addButton) {
                addButton = [UIButton buttonWithType:UIButtonTypeCustom];
                addButton.tag = GLGRIDDEFAULT_EDIT_ADD_TAG;
                
                addButton.frame = CGRectMake(0, 0, self.addBtnSize.width, self.addBtnSize.height);
            
                [addButton addTarget:self action:@selector(addItem:) forControlEvents:UIControlEventTouchUpInside];
                if (self.addImage) {
                    [addButton setImage:self.addImage forState:UIControlStateNormal];
                }else{
                    [addButton setTitle:@"添加" forState:UIControlStateNormal];
                    addButton.backgroundColor = [UIColor greenColor];
                }
                addButton.center = cell.contentView.center;
                [cell.contentView addSubview:addButton];
            }
            
        }else{
            UIButton* addButton = [cell.contentView viewWithTag:GLGRIDDEFAULT_EDIT_ADD_TAG];
            if (addButton) {
                [addButton removeFromSuperview];
            }
        }

    }
    
    
    //添加网格
    if (self.showLine) {
        cell.contentView.layer.borderColor = self.lineColor.CGColor;
        cell.contentView.layer.borderWidth = self.lineWidth;
        cell.contentView.clipsToBounds = YES;
    }
    
    return cell;
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    //点击事件回调
    if (self.didWhenSelectItem && indexPath.row < self.dataArray.count) {
        self.didWhenSelectItem(collectionView,indexPath);
    }
}


#pragma mark-
- (void)addItem:(UIButton*)btn{
    if (self.didWhenAddClickedItem) {
        self.didWhenAddClickedItem(self.collectionView);
    }
}
- (void)deleteCell:(UIButton*)btn{
    UICollectionViewCell* cell = (UICollectionViewCell*)btn.superview.superview;
    NSIndexPath* indexPath = [self.collectionView indexPathForCell:cell];
    if (!indexPath) {
        return;
    }
    NSInteger curCount = self.allCount;
    [self.dataArray removeObjectAtIndex:indexPath.item];
    
    [self.collectionView performBatchUpdates:^{
        //删除数据原素
        [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
        
        if (self.allCount == curCount) {//如果删除一个数据后，总数不变，需要添加一个占位CELL kNullCellID
            [self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:self.allCount-1 inSection:0]]];
        }
        else{//如果删除一个数据后，行数减少，需要删除所有的占位CELL kNullCellID
            NSInteger count = curCount-self.dataArray.count;
            if ([self judgeOperationType:self.itemAddType]) {//如果有add，减去
                count--;
            }
            NSMutableArray *delArray = [NSMutableArray arrayWithCapacity:0];
            for (NSInteger i = 1;i<count;i++) {
                [delArray addObject:[NSIndexPath indexPathForItem:curCount-i inSection:0]];
            
            }
            [self.collectionView deleteItemsAtIndexPaths:delArray];
        }
    } completion:^(BOOL finished) {
        if (self.didWhenDeletedItem) {
            self.didWhenDeletedItem(self.collectionView, self.dataArray);
        }
    }];


}

- (void)longPressAction:(UILongPressGestureRecognizer *)longPress {
    //获取此次点击的坐标，根据坐标获取cell对应的indexPath
    CGPoint point = [longPress locationInView:_collectionView];
    CGPoint selfPoint = [self convertPoint:point fromView:_collectionView];
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
    UICollectionViewCell* cell = [self.collectionView cellForItemAtIndexPath:indexPath];

    //根据长按手势的状态进行处理。
    switch (longPress.state) {
        case UIGestureRecognizerStateBegan:
        {
            if (self.moveItem) {
                [self.moveItem removeFromSuperview];
                self.moveItem = nil;
            }
            //当没有点击到cell的时候不进行处理
            if (!cell || [cell.reuseIdentifier isEqualToString:kNullCellID]) {
                break;
            }
            //开始移动
            UIGraphicsBeginImageContextWithOptions(cell.contentView.bounds.size, 1, [UIScreen mainScreen].scale);

            CGContextRef ctx = UIGraphicsGetCurrentContext();
            [cell.layer renderInContext:ctx];
            UIImage *imageRef = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            
            CGRect newFrame = [self convertRect:cell.frame fromView:_collectionView];
            self.curMoveIndexPath = [indexPath copy];
            self.moveItem = [[UIImageView alloc]initWithFrame:newFrame];
            self.moveItem.image = imageRef;
            self.moveItem.layer.shadowColor = [UIColor lightGrayColor].CGColor;
            self.moveItem.layer.shadowOffset = CGSizeMake(1, 1);
            self.moveItem.layer.shadowOpacity = 0.8;
            self.moveItem.layer.shadowRadius = 3;
            
            self.orignIndexPath = [indexPath copy];
            [self addSubview:self.moveItem];
            [UIView animateWithDuration:0.2 animations:^{
                self.moveItem.frame = CGRectMake(0, 0, cell.bounds.size.width*1.1, cell.bounds.size.height*1.1);
                self.moveItem.center = selfPoint;
                cell.contentView.alpha = 0;
                cell.backgroundColor = [UIColor colorWithRed:222.0/255.0 green:222.0/255.0 blue:222.0/255.0 alpha:1];
            }];
            
            break;
        }
        case UIGestureRecognizerStateChanged:
        {
            //移动过程中更新位置坐标
            if (!self.moveItem) {
                break;
            }
            self.moveItem.center = selfPoint;
            if ([cell.reuseIdentifier isEqualToString:kNullCellID]) {
                return;
            }
            if (indexPath && ![self.curMoveIndexPath isEqual:indexPath]) {
                [_collectionView moveItemAtIndexPath:self.curMoveIndexPath toIndexPath:indexPath];
                id value = [self.dataArray objectAtIndex:self.curMoveIndexPath.row];
                [self.dataArray removeObject:value];
                [self.dataArray insertObject:value atIndex:indexPath.row];
                self.curMoveIndexPath = [indexPath copy];
            }
            
//            if (point.y < 40) {
//                CGFloat newContentOffsetY = _collectionView.contentOffset.y-60;
//                newContentOffsetY = newContentOffsetY<0?0:newContentOffsetY;
//                [_collectionView setContentOffset:CGPointMake(0, newContentOffsetY) animated:YES];
//            }
//            else if (point.y > _collectionView.bounds.size.height-40){
//                CGFloat newContentOffsetY = _collectionView.contentOffset.y+60;
//                newContentOffsetY = newContentOffsetY>_collectionView.contentSize.height?_collectionView.contentSize.height:newContentOffsetY;
//                [_collectionView setContentOffset:CGPointMake(0, newContentOffsetY) animated:YES];
//            }
            
            break;
        }
        default:
        {
            //停止移动调用此方法
            if (!self.moveItem) {
                break;
            }
            UICollectionViewCell* destcell = [self.collectionView cellForItemAtIndexPath:self.curMoveIndexPath];
            CGRect newFrame = [self convertRect:destcell.frame fromView:_collectionView];
            if (self.didWhenMovedItem) {
                self.didWhenMovedItem(self.collectionView, self.dataArray);
            }
            [UIView animateWithDuration:0.2f animations:^{
                self.moveItem.frame = newFrame;
                
            } completion:^(BOOL finished) {
                destcell.contentView.alpha = 1;
                cell.backgroundColor = [UIColor whiteColor];
                [self.moveItem removeFromSuperview];
                self.moveItem = nil;
            }];
            break;
        }
        
    }
}



#pragma mark - setter / getter
- (UICollectionView *)collectionView
{
    if (!_collectionView)
    {
        GLGridViewLayout *flowLayout = [GLGridViewLayout new];
        flowLayout.rowCount = _rowCount;
        flowLayout.itemHeight = _itemHeight;
        flowLayout.showLine = _showLine;
        
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
        _collectionView.backgroundColor = [UIColor whiteColor];
        NSAssert(self.registerCellClass != nil, @"registerCellClass can't been nil");
        [_collectionView registerClass:self.registerCellClass forCellWithReuseIdentifier:kCellID];
        [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kNullCellID];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        
    }
    return _collectionView;
}


- (void)setDataArray:(NSArray *)dataArray{
    if (_dataArray != dataArray) {
        _dataArray = [dataArray mutableCopy];

    }
}

- (NSInteger)allCount{
    NSInteger nulNum = 0;
    NSInteger dataNum= _dataArray.count;
    if ([self judgeOperationType:self.itemAddType]) {
        dataNum++;
    }
    NSInteger row = dataNum%self.rowCount;
    //计算数据源数量，不满时添加凑够一行
    if (row != 0) {
        nulNum+=self.rowCount-row;
    }
    _allCount= dataNum+nulNum;
    
    return _allCount;
}

- (void)setEditable:(BOOL)editable{
    if (_editable != editable) {
        _editable = editable;
        [self reloadData];
    }
}

@end


#pragma mark- CLASS GLGridViewLayout


@implementation GLGridViewLayout


/*
 @description 布局开时预备工作
 */
-(void)prepareLayout
{
    [super prepareLayout];
    [self.attrsArr removeAllObjects];
    self.lineWidth = GLGRIDDEFAULT_LINEWIDTH;
    NSInteger count =[self.collectionView   numberOfItemsInSection:0];
    for (int i=0; i<count; i++) {
        NSIndexPath *  indexPath =[NSIndexPath indexPathForItem:i inSection:0];
        UICollectionViewLayoutAttributes * attrs=[self layoutAttributesForItemAtIndexPath:indexPath];
        [self.attrsArr addObject:attrs];
    }
}

-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    return self.attrsArr;
}

#pragma mark ---- 返回CollectionView的内容大小
/*!
 * 计算内容SIZE
 */
-(CGSize)collectionViewContentSize
{
    NSInteger column = [self.collectionView numberOfItemsInSection:0]/self.rowCount;
    
    return CGSizeMake(0, self.itemHeight*column);
}



-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes * attrs=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    /***/
    CGFloat itemHeight = self.itemHeight;
    CGFloat xOffset = 0;
    CGFloat yOffset = 0;
    CGFloat itemWidth = ((NSInteger)self.collectionView.bounds.size.width)/self.rowCount;
    
    
    NSInteger row = indexPath.row%self.rowCount;
    NSInteger column = indexPath.row/self.rowCount;
    
    xOffset+=row*itemWidth;
    yOffset+=column*itemHeight;
    
    //整数规划CELL宽度，多余值放到最后一列，最后列看起来可能比其它列略宽
    if (row == self.rowCount-1) {
        NSInteger xx = ((NSInteger)self.collectionView.bounds.size.width)%self.rowCount;
        itemWidth+=xx;
    }
    
    if (self.showLine) {
        //画线时，缩进一个线宽距离，保证网格周围网格线宽度一致
        //非首列，全部向左位移一个线宽，同时增加自身宽度一个线宽
        if (row > 0) {
            xOffset-=self.lineWidth;
            itemWidth+=self.lineWidth;
        }
        //非首行，全部向上位移一个线宽，同时增加自身高度一个线宽
        if (column > 0) {
            yOffset-=self.lineWidth;
            itemHeight+=self.lineWidth;
        }
    }
    
    
    
    attrs.frame = CGRectMake(xOffset, yOffset, itemWidth, itemHeight);
    
    
    return attrs;
}

#pragma mark- setter and getter
-(NSMutableArray *)attrsArr
{
    if(!_attrsArr){
        _attrsArr=[[NSMutableArray alloc] init];
    }
    return _attrsArr;
}


@end
